﻿using IdentityModel.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace PhoneCodeLoginBlzWeb.Data
{
    /// <summary>
    /// 手机验证码登录功能模块
    /// </summary>
    public class Ids4Client
    {
        private readonly HttpClient _client;

        public Ids4Client(HttpClient httpClient)
        {
            _client = httpClient;
        }

        /// <summary>
        /// 发送验证码到手机号
        /// </summary>
        /// <param name="phoneNumber"></param>
        /// <returns></returns>
        public async Task<string> SendPhoneCodeAsync(string phoneNumber)
        {
            string url = $"api/PhoneCodeLogin/SendPhoneCode?phoneNumber={phoneNumber}";

            string result = await _client.GetStringAsync(url);

            return result;
        }

        /// <summary>
        /// 手机验证码登录
        /// </summary>
        /// <param name="phoneNumber">手机号</param>
        /// <param name="verificationCode">验证码</param>
        /// <returns></returns>
        public async Task<(TokenResponse tokenResponse, string userInfoJson)> PhoneCodeLogin(string phoneNumber, string verificationCode)
        {
            var request = new DiscoveryDocumentRequest()
            {
                Policy = new DiscoveryPolicy()
                {
                    //本地调试抓包
                    RequireHttps = false
                }
            };

            //发现端点
            var discovery = await _client.GetDiscoveryDocumentAsync(request);

            if (discovery.IsError)
            {
                Console.WriteLine($"访问Identity Server 4服务器失败, Error={discovery.Error}");
                return (null, null);
            }

            //填写登录参数，必须跟Identity Server 4服务器Config.cs定义一致
            var requestParams = new Dictionary<string, string>
            {
                ["client_Id"] = "PhoneCode",
                ["client_secret"] = "PhoneCode.Secret",
                ["grant_type"] = "PhoneCodeGrantType",
                ["scope"] = "openid profile scope1 role",
                ["PhoneNumber"] = phoneNumber,
                ["VerificationCode"] = verificationCode
            };

            //请求获取token
            var tokenResponse = await _client.RequestTokenRawAsync(discovery.TokenEndpoint, requestParams);
            if (tokenResponse.IsError)
            {
                Console.WriteLine($"请求获取token失败, Error={tokenResponse.Error}");
                return (null, null);
            }

            string userInfoJson = "";

            //设置Http认证头
            _client.SetBearerToken(tokenResponse.AccessToken);

            //获取用户信息
            var userInfoResponse = await _client.GetAsync(discovery.UserInfoEndpoint);
            if (!userInfoResponse.IsSuccessStatusCode)
            {
                //scope必须包含profile才能获取到用户信息
                //如果客户端请求scope没有profile，返回403拒绝访问
                Console.WriteLine($"获取用户信息失败, StatusCode={userInfoResponse.StatusCode}");
            }
            else
            {
                // {"sub":"d2f64bb2-789a-4546-9107-547fcb9cdfce","name":"Alice Smith","given_name":"Alice","family_name":"Smith","website":"http://alice.com","role":["Admin","Guest"],"preferred_username":"alice"}
                userInfoJson = await userInfoResponse.Content.ReadAsStringAsync();
                Console.WriteLine($"获取用户信息成功, {userInfoJson}");
            }

            return (tokenResponse, userInfoJson);
        }
    }
}
